
use std::fmt::Write;
use std::sync::Arc;
use chrono::Local;
use spdlog::{info, LevelFilter, Logger, Record, StringBuf};
use spdlog::formatter::{Formatter, FormatterContext};
use spdlog::sink::{AsyncPoolSink, FileSink};

#[derive(Clone, Default)]
struct MyCustomFormatter;

const LOG_LEVEL_SHORT_NAMES: [&str; 6] = ["C", "E", "W", "I", "D", "T"];
fn get_short_str(index: usize) -> &'static str {
    LOG_LEVEL_SHORT_NAMES[index]
}

impl Formatter for MyCustomFormatter {
    fn format(
        &self,
        record: &Record,
        dest: &mut StringBuf,
        _ctx: &mut FormatterContext,
    ) -> spdlog::Result<()> {

        let level = record.level();
        let msg = record.payload();

        // 获取时间戳
        let timestamp = Local::now().format("%Y-%m-%d %a %H:%M:%S.%3f").to_string();
        let file_name = record.source_location().unwrap().file_name();
        let file_line = record.source_location().unwrap().line();

        writeln!(dest,
                 "[{}] <{}> [{}] [{:8}:{:>3}] {}",
                 timestamp,record.tid(), get_short_str(level as usize), file_name, file_line, msg
        ).map_err(spdlog::Error::FormatRecord)?;

        Ok(())
    }
}

pub fn init_log(log_path: String) -> Result<(), spdlog::Error> {
    // 需要确保 FileSink 和日志的构造正确
    let file_sink = Arc::new(FileSink::builder()
        .path(log_path)
        .build()?);

    let async_pool_sink = Arc::new(AsyncPoolSink::builder().sink(file_sink).build()?);
    let async_logger = Arc::new(
        Logger::builder()
            .sink(async_pool_sink)
            .flush_level_filter(LevelFilter::All)
            .build()?,
    );

    let my_formatter = Box::new(MyCustomFormatter::default());

    // 设置每个 sink 的格式化器
    for sink in async_logger.sinks() {
        sink.set_formatter(my_formatter.clone());
    }

    // 设置为默认 logger
    spdlog::set_default_logger(async_logger);

    // 打印一条日志测试输出
    info!("logger initialized successfully!");

    Ok(())
}